%slatex.sty
%SLaTeX Version 1.99
%style file to be used in (La)TeX when using SLaTeX
%(c) Dorai Sitaram, December 1991, Rice University

% This file (or a soft link to it) should be in some directory
% in your TEXINPUTS path (i.e., the one (La)TeX scours for \input
% or \documentstyle option files).

% Do not attempt to debug this file, since the results are not
% transparent just to (La)TeX.  The Scheme part of SLaTeX depends
% on information laid out here -- so (La)TeX-minded debugging of
% this file will almost inevitably sabotage SLaTeX.

% It's possible you don't find the default style set out here 
% appealing: e.g., you may want to change the positioning of displayed
% code; change the fonts for keywords, constants, and variables; add
% new keywords, constants, and variables; use your names instead of
% the provided \scheme, [\begin|\end]{schemedisplay},
% [\begin|\end]{schemebox}, (or \[end]schemedisplay, \[end]schemebox
% for TeX), which might be seem too long or unmnemonic, and many other
% things.  The clean way to do these things is outlined in the
% accompanying manual, slatex-d.tex.  This way is both easier than
% messing with this .sty file, and safer since you will not
% unwittingly break SLaTeX.

% use \slatexignorecurrentfile to disable slatex for the current file

\def\slatexignorecurrentfile{}

% checking whether we're using LaTeX or TeX?

\newif\ifusinglatex
\ifx\newenvironment\UNDEFINED\usinglatexfalse\else\usinglatextrue\fi

%make @ a letter for TeX
\ifusinglatex\relax\else\catcode`\@=11\fi

%identification
\ifusinglatex\gdef\latex@rtex{latex}\else\gdef\latex@rtex{tex}\fi

\ifusinglatex\relax\else\gdef\sf{\rm}\fi

% tabbing from plain TeX
%
\newif\ifus@ \newif\if@cr
\newbox\tabs \newbox\tabsyet \newbox\tabsdone
%
\def\cleartabs{\global\setbox\tabsyet\null \setbox\tabs\null}
\def\settabs{\setbox\tabs\null \futurelet\next\sett@b}
\let\+=\relax % in case this file is being read in twice
\def\sett@b{\ifx\next\+\let\next\relax
    \def\next{\afterassignment\s@tt@b\let\next}%
  \else\let\next\s@tcols\fi\next}
\def\s@tt@b{\let\next\relax\us@false\m@ketabbox}
\def\tabalign{\us@true\m@ketabbox} % non-\outer version of \+
\outer\def\+{\tabalign}
\def\s@tcols#1\columns{\count@#1 \dimen@\hsize
  \loop\ifnum\count@>\z@ \@nother \repeat}
\def\@nother{\dimen@ii\dimen@ \divide\dimen@ii\count@
  \setbox\tabs\hbox{\hbox to\dimen@ii{}\unhbox\tabs}%
  \advance\dimen@-\dimen@ii \advance\count@\m@ne}
%
\def\m@ketabbox{\begingroup
  \global\setbox\tabsyet\copy\tabs
  \global\setbox\tabsdone\null
  \def\cr{\@crtrue\crcr\egroup\egroup
    \ifus@\unvbox\z@\lastbox\fi\endgroup
    \setbox\tabs\hbox{\unhbox\tabsyet\unhbox\tabsdone}}%
  \setbox\z@\vbox\bgroup\@crfalse
    \ialign\bgroup&\t@bbox##\t@bb@x\crcr}
%
\def\t@bbox{\setbox\z@\hbox\bgroup}
\def\t@bb@x{\if@cr\egroup % now \box\z@ holds the column
  \else\hss\egroup \global\setbox\tabsyet\hbox{\unhbox\tabsyet
      \global\setbox\@ne\lastbox}% now \box\@ne holds its size
    \ifvoid\@ne\global\setbox\@ne\hbox to\wd\z@{}%
    \else\setbox\z@\hbox to\wd\@ne{\unhbox\z@}\fi
    \global\setbox\tabsdone\hbox{\box\@ne\unhbox\tabsdone}\fi
  \box\z@}
%
%\fi % finished (re)defining TeX's tabbing macros

% above from plain.tex; was disabled in lplain.tex
% do not modify above unless you really know what you're up to
% make all changes you want to following code
% the new env preferable to LaTeX's tabbing env since 
% latter accepts only a small number of tabs

% following retrieves something like LaTeX's tabbing env 
% without the above problem
% (it also creates a box for easy manipulation!)

\def\lat@xtabbing{\leavevmode\hbox\bgroup\vbox\bgroup
 \def\={\cleartabs&} \def\>{&} \def\\{\cr\tabalign} \tabalign}
\def\endlat@xtabbing{\cr\egroup\egroup}

% stuff for formating Scheme code

\newskip\par@nlen \newskip\brack@tlen \newskip\quot@len
\newskip\h@lflambda

\newbox\garb@ge
\def\s@ttowidth#1#2{\setbox\garb@ge\hbox{#2}#1\wd\garb@ge\relax}

\s@ttowidth\par@nlen{$($}       %size of paren
\s@ttowidth\brack@tlen{$[$}     %size of bracket
\s@ttowidth\quot@len{'}         %size of quote indentation
\s@ttowidth\h@lflambda{ii}      %size of half of lambda indentation

\def\PRN{\hskip\par@nlen}       %these are used by SLaTeX's codesetter
\def\BKT{\hskip\brack@tlen} 
\def\QUO{\hskip\quot@len}
\def\HL{\hskip\h@lflambda}

\begingroup
\catcode`\|=0
|catcode`|\=12
|gdef|ttbackslash{{|tt|catcode`|\=12\}}
|endgroup

\newskip\abovecodeskip \newskip\belowcodeskip
\newskip\leftcodeskip \newskip\rightcodeskip

% the following default assignments give a flushleft display

\abovecodeskip=\medskipamount \belowcodeskip=\medskipamount
\leftcodeskip=0pt \rightcodeskip=0pt

% the following are the default font assignments for words in code
% change them to suit personal taste

\def\keywordfont#1{{\bf #1}} 
\def\variablefont#1{{\it #1\/}} 
\def\constantfont#1{{\sf #1}}
\def\datafont#1{\constantfont{#1}}

\def\ZZZZschemecodehook{}

\def\ZZZZschemecode{\begingroup\ZZZZschemecodehook
 \vskip\abovecodeskip\noindent\hskip\leftcodeskip
 \let\sy=\keywordfont \let\cn=\constantfont 
 \let\va=\variablefont \let\dt=\datafont% to make schtex's o/p less unreadable
 \lat@xtabbing}
\def\endZZZZschemecode{\endlat@xtabbing
 \hskip\rightcodeskip\vskip\belowcodeskip
 \endgroup}

\def\ZZZZschemecodeintext{\begingroup\ZZZZschemecodehook
  \let\sy\keywordfont \let\cn\constantfont
  \let\va\variablefont \let\dt\datafont
  \begingroup}
\def\endZZZZschemecodeintext{\endgroup\endgroup}

\def\ZZZZschemeresultintext{\begingroup\ZZZZschemecodehook
  \let\sy\datafont \let\cn\constantfont
  \let\va\datafont \let\dt\datafont
  \begingroup}
\def\endZZZZschemeresultintext{\endgroup\endgroup}

\def\ZZZZschemecodebox{\begingroup\ZZZZschemecodehook
 \let\sy=\keywordfont \let\cn=\constantfont 
 \let\va=\variablefont \let\dt=\datafont% to make schtex's o/p less unreadable
 \lat@xtabbing}
\def\endZZZZschemecodebox{\endlat@xtabbing\endgroup}

% for alternate centered code style
%
%\leftcodeskip=0pt plus 1fil
%\rightcodeskip=0pt plus 1fil

% adjust above,below,left,right codeskip's to personal taste

% \comm@nt<some-char>...text...<same-char> comments out TeX source
% analogous to \verb<some-char>...text...<same-char>
% sp. case: \comm@nt{...text...} == \comm@nt}...text...}

\def\@makeother#1{\catcode`#112\relax}

\def\comm@nt{%
  \begingroup
  \let\do\@makeother \dospecials
  \@comm}

\def\word@nd{\hskip-.35em\penalty\@M\null}

\begingroup\catcode`\<1\catcode`\>2
\catcode`\{12\catcode`\}12
\long\gdef\@comm#1<%
  \if#1{\long\def\@tempa ##1}<\endgroup\word@nd>\else
	\long\def\@tempa ##1#1<\endgroup\word@nd>\fi
  \@tempa>
\endgroup

% input file if possible, else relax

\newread\inp@tport
\def\inputifposs@ble#1{%
  \immediate\openin\inp@tport=#1\relax%
  \ifeof\inp@tport\relax\else\input#1\relax\fi%
  \closein\inp@tport}

\def\ZZZZinput#1{\input#1\relax}

% you may replace the above by
%
% \def\ZZZZinput#1{\inputifposs@ble{#1}}
%
% if you just want to call (La)TeX on your text ignoring the
% portions that need to be SLaTeX'ed

% counter for generating temp file names

\newcount\sch@mefilenamecount
\sch@mefilenamecount=0

% To produce displayed Scheme code:
% in LaTeX:
% \begin{schemedisplay}
%   ... indented program (with sev'l lines) ...
% \end{schemedisplay}
%
% in TeX:
% \schemedisplay
%   ... indented program (with sev'l lines) ...
% \endschemedisplay

\begingroup\catcode`\|=0\catcode`\[=1\catcode`\]=2%
\catcode`\{=12\catcode`\}=12\catcode`\\=12%
|gdef|defschemedisplaytoken#1[%
  |long|expandafter|gdef|csname ZZZZcomment#1|endcsname[%
    |begingroup
    |let|do|@makeother |dospecials
    |csname ZZZZcomment|latex@rtex II#1|endcsname]%
  |long|expandafter|gdef|csname ZZZZcommentlatexII#1|endcsname##1\end{#1}[%
    |endgroup|end[#1]]%
  |long|expandafter|gdef|csname ZZZZcommenttexII#1|endcsname##1\end#1[%
    |endgroup|csname end#1|endcsname]%
  |long|expandafter|gdef|csname #1|endcsname[%
    |global|advance|sch@mefilenamecount by 1%
    |ZZZZinput[|filehider Z|number|sch@mefilenamecount|jobname.tex]%
    |csname ZZZZcomment#1|endcsname]%
  |long|expandafter|gdef|csname end#1|endcsname[]]%
|endgroup

\defschemedisplaytoken{schemedisplay}
    
\def\undefschemedisplaytoken#1{%
  \expandafter\gdef\csname#1\endcsname{\UNDEFINED}}

% \scheme|...program fragment...| produces Scheme code in-text
% sp. case: \scheme{...} == \scheme}...}

\def\defschemetoken#1{%
  \long\expandafter\def\csname#1\endcsname{%
    \global\advance\sch@mefilenamecount by 1%
    \ZZZZinput{\filehider Z\number\sch@mefilenamecount\jobname.tex}%
    \comm@nt}}
\defschemetoken{scheme}

\def\undefschemetoken#1{%
  \expandafter\gdef\csname#1\endcsname{\UNDEFINED}}

% \schemeresult|...program fragment...| produces a Scheme code result
% in-text: i.e. keyword or variable fonts are replaced by the data font.
% sp. case: \schemeresult{...} == \schemeresult}...}

\def\defschemeresulttoken#1{%
  \long\expandafter\def\csname#1\endcsname{%
    \global\advance\sch@mefilenamecount by 1%
    \ZZZZinput{\filehider Z\number\sch@mefilenamecount\jobname.tex}%
    \comm@nt}}
\defschemeresulttoken{schemeresult}

\def\undefschemeresulttoken#1{%
  \expandafter\gdef\csname#1\endcsname{\UNDEFINED}}

% To produce a box of Scheme code:
% in LaTeX:
% \begin{schemebox}
%   ... indented program (with sev'l lines) ...
%  \end{schemebox}
%
% in TeX:
% \schemebox
%   ... indented program (with sev'l lines) ...
% \endschemebox

\begingroup\catcode`\|=0\catcode`\[=1\catcode`\]=2%
\catcode`\{=12\catcode`\}=12\catcode`\\=12%
|gdef|defschemeboxtoken#1[%
  |long|expandafter|gdef|csname ZZZZcomment#1|endcsname[%
    |begingroup
    |let|do|@makeother |dospecials
    |csname ZZZZcomment|latex@rtex II#1|endcsname]%
  |long|expandafter|gdef|csname ZZZZcommentlatexII#1|endcsname##1\end{#1}[%
    |endgroup|end[#1]]%
  |long|expandafter|gdef|csname ZZZZcommenttexII#1|endcsname##1\end#1[%
    |endgroup|csname end#1|endcsname]%
  |long|expandafter|gdef|csname #1|endcsname[%
    |global|advance|sch@mefilenamecount by 1%
    |ZZZZinput[|filehider Z|number|sch@mefilenamecount|jobname.tex]%
    |csname ZZZZcomment#1|endcsname]%
  |long|expandafter|gdef|csname end#1|endcsname[]]%
|endgroup

\defschemeboxtoken{schemebox}
    
\def\undefschemeboxtoken#1{%
  \expandafter\gdef\csname#1\endcsname{\UNDEFINED}}

% for wholesale dumping of all-Scheme files into TeX (converting
% .ss files to .tex),
% use
%   \schemeinput{<filename>}
% .ss extension optional

\def\defschemeinputtoken#1{%
  \long\expandafter\gdef\csname#1\endcsname##1{%
    \global\advance\sch@mefilenamecount by 1%
    \ZZZZinput{\filehider Z\number\sch@mefilenamecount\jobname.tex}}}
\defschemeinputtoken{schemeinput}

\def\undefschemeinputtoken#1{%
  \expandafter\gdef\csname#1\endcsname{\UNDEFINED}}

% delineating a region that features typeset code
% not usually needed, except when using \scheme and schemedisplay
% inside macro-args and macro-definition-bodies
% in LaTeX:
% \begin{schemeregion}
%   ...
% \end{schemeregion}
%
% in TeX:
% \schemeregion
% ...
% \endschemeregion

\begingroup\catcode`\|=0\catcode`\[=1\catcode`\]=2%
\catcode`\{=12\catcode`\}=12\catcode`\\=12%
|gdef|defschemeregiontoken#1[%
  |long|expandafter|gdef|csname ZZZZcomment#1|endcsname[%
    |begingroup
    |let|do|@makeother |dospecials
    |csname ZZZZcomment|latex@rtex II#1|endcsname]%
  |long|expandafter|gdef|csname ZZZZcommentlatexII#1|endcsname##1\end{#1}[%
    |endgroup|end[#1]]%
  |long|expandafter|gdef|csname ZZZZcommenttexII#1|endcsname##1\end#1[%
    |endgroup|csname end#1|endcsname]%
  |long|expandafter|gdef|csname #1|endcsname[%
    |global|advance|sch@mefilenamecount by 1%
    |ZZZZinput[|filehider Z|number|sch@mefilenamecount|jobname.tex]%
    |csname ZZZZcomment#1|endcsname]%
  |long|expandafter|gdef|csname end#1|endcsname[]]%
|endgroup

\defschemeregiontoken{schemeregion}
    
\def\undefschemeregiontoken#1{%
  \expandafter\gdef\csname#1\endcsname{\UNDEFINED}}

% introducing new code-tokens to the keyword, variable and constant 
% categories 

\def\comm@ntII{%
  \begingroup
  \let\do\@makeother \dospecials
  \@commII}

\begingroup\catcode`\[1\catcode`\]2
\catcode`\{12\catcode`\}12
\long\gdef\@commII{[%
  \long\def\@tempa ##1}[\endgroup]\@tempa]%
\endgroup

\let\setkeyword\comm@ntII
\let\setvariable\comm@ntII
\let\setconstant\comm@ntII

% \defschememathescape makes the succeeding grouped character an
% escape into latex math from within Scheme code;
% this character can't be }

\let\defschememathescape\comm@ntII
\let\undefschememathescape\comm@ntII

% telling SLaTeX that a certain Scheme identifier is to be replaced by
% the specified LaTeX expression.  Useful for generating
% ``mathematical''-looking typeset code even though the corresponding
% Scheme code is ascii as usual and doesn't violate identifier-naming
% rules

\def\setspecialsymbol{%
  \begingroup
  \let\do\@makeother \dospecials
  \@commIII}

\begingroup\catcode`\[1\catcode`\]2
\catcode`\{12\catcode`\}12
\long\gdef\@commIII{[%
  \long\def\@tempa ##1}[\endgroup\@gobbleI]\@tempa]%
\endgroup  

\def\@gobbleI#1{}

% \unsetspecialsymbol strips Scheme identifier(s) of any
% ``mathematical'' look lent by the above

\let\unsetspecialsymbol\comm@ntII

% enabling/disabling slatex

\def\slatexdisable#1{\expandafter\gdef\csname#1\endcsname{}}

% \schemecasesensitive takes either true or false as argument

\def\schemecasesensitive#1{}

% alternate names for some characters in case these are redefined

\mathchardef\lt="313C
\mathchardef\gt="313E
\begingroup
  \catcode`\@12%
  \global\let\atsign@%
\endgroup
\chardef\dq=`\"

% leading character of slatex filenames: . for unix to keep them
% out of the way

\def\filehider{.}

% since the above doesn't work of dos, slatex on dos will use a 
% different character, and make the redefinition available through
% the following

\inputifposs@ble{filehide.jnk}

% @ is no longer a letter for TeX

\ifusinglatex\relax\else\catcode`@=12\fi

\message{*** Check: are you sure you called SLaTeX? ***}

